home *** CD-ROM | disk | FTP | other *** search
/ Info-Mac 4 / Info_Mac IV CD-ROM (Pacific HiTech Inc.)(August 1994).iso / Development / Source / Macintosh Tracker Source / Tracker Client Folder / Core 18⁄March⁄1994 / Object Access Code / ClassNewInd.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-08-01  |  3.2 KB  |  203 lines  |  [TEXT/KAHL]

  1. #define INDIRECT
  2.  
  3. /*
  4.  *  new.c - create a new object
  5.  *
  6.  *  Copyright (c) 1991 Symantec Corporation.  All rights reserved.
  7.  *
  8.  */
  9.  
  10. #define OOPS_PRIVATE
  11. #include "oops.h"
  12.  
  13. #ifdef INDIRECT
  14.     #define __new __new_indirect
  15. #else
  16.     #define __new __new_direct
  17. #endif
  18.  
  19. extern void *__new(...);
  20.  
  21.  
  22. /*
  23.  *  __new - create a new object
  24.  *
  25.  *  The compiler, for
  26.  *
  27.  *        obj = new C;
  28.  *
  29.  *  generates:
  30.  *
  31.  *            PEA        C
  32.  *            JSR        __new
  33.  *            ADDQ.L    #4,SP
  34.  *            MOVE.L    D0,obj
  35.  *
  36.  *  This routine allocates the object, calling an appropriate "operator new"
  37.  *  method if available, and calls the constructors for the class and each of
  38.  *  its superclasses in turn, root class first.
  39.  *
  40.  *  The new object is returned in D0.  If the object could not be allocated,
  41.  *  0 is returned.
  42.  *
  43.  */
  44.  
  45. void *
  46. __new()
  47. {
  48.     asm {
  49.         link    a6,#0
  50.         movem.l    d6/d7/a2,-(sp)
  51.  
  52. ;;
  53. ;
  54. ;  initiate recursive traversal of superclass chain
  55. ;
  56. ;;
  57.  
  58.         move.l    8(a6),d6            ;  D6 = class Ref
  59.     #ifdef BASE_REG
  60.         sub.l    BASE_REG,d6
  61.     #endif
  62.         moveq    #0,d0                ;  D0.L = size (unknown)
  63.         moveq    #0,d7                ;  D7 ==> object (unallocated)
  64.         bsr.s    @do_new
  65.  
  66. ;;
  67. ;
  68. ;  done
  69. ;
  70. ;;
  71.  
  72. abort:
  73.         move.l    d7,d0
  74.         movem.l    -12(a6),d6/d7/a2
  75.         unlk    a6
  76.         rts
  77.  
  78. ;;
  79. ;
  80. ;  The remainder is a recursive routine, "@do_new".
  81. ;
  82. ;  "@do_new" recursively traverses the superclass chain.  On the way down,
  83. ;  it tries to allocate the object using the first allocator it finds; if
  84. ;  the root is reached without finding an allocator, the default allocator
  85. ;  is used.  If an allocator is called and fails, we jump immediately to
  86. ;  "@abort", above, which cleans up the stack, restores registers, and
  87. ;  returns 0 without further ado.
  88. ;
  89. ;  On the way back up, it sets the object's class Ref appropriately and
  90. ;  calls any constructors.
  91. ;
  92. ;;
  93.  
  94. do_new:
  95.  
  96. ;;
  97. ;
  98. ;  set A2 ==> class info
  99. ;
  100. ;;
  101.  
  102.         movea._    d6,a2
  103.     #ifdef BASE_REG
  104.         adda.l    BASE_REG,a2
  105.     #endif
  106.         moveq    #1,d1
  107.         add.w    (a2)+,d1
  108.         lsl.w    #DSHIFT,d1
  109.         adda.w    d1,a2
  110.  
  111. ;;
  112. ;
  113. ;  set D0 = number of bytes to allocate
  114. ;
  115. ;;
  116.  
  117.         tst.l    d7
  118.         bne.s    @3                    ;  object already allocated
  119.         tst.l    d0
  120.         bne.s    @1                    ;  size already determined
  121.         move.l    ClassInfo_(size)(a2),d0            
  122.  
  123. ;;
  124. ;
  125. ;  allocate object using "operator new" from this class
  126. ;
  127. ;;
  128.  
  129. @1        move._    ClassInfo_(allocator)(a2),d1
  130.         beq.s    @2                    ;  class doesn't have allocator
  131. ;
  132.         movea._    d1,a0
  133.     #ifdef BASE_REG
  134.         adda.l    BASE_REG,a0
  135.     #endif
  136.         move.l    d0,-(sp)
  137.         jsr        (a0)
  138.         addq.l    #4,sp
  139.         move.l    d0,d7
  140.         bne.s    @3
  141.         bra.s    @abort                ;  object could not be allocated
  142.  
  143. ;;
  144. ;
  145. ;  allocate object using default allocator
  146. ;
  147. ;;
  148.  
  149. @2        move._    ClassInfo_(superclass)(a2),d1
  150.         bne.s    @3                    ;  haven't reached root class yet
  151. ;
  152.     #ifdef INDIRECT
  153.         _NewHandle CLEAR
  154.     #else
  155.         _NewPtr CLEAR
  156.     #endif
  157.         move.l    a0,d7
  158.         beq.s    @abort                ;  object could not be allocated
  159.  
  160. ;;
  161. ;
  162. ;  recurse to superclass
  163. ;
  164. ;;
  165.  
  166. @3        movem.l    d6/a2,-(sp)
  167.         move._    ClassInfo_(superclass)(a2),d6
  168.         beq.s    @4                    ;  reached root
  169.         bsr.s    @do_new
  170. @4        movem.l    (sp)+,d6/a2
  171.  
  172. ;;
  173. ;
  174. ;  set class Ref in object
  175. ;
  176. ;;
  177.  
  178.         movea.l    d7,a0
  179.     #ifdef INDIRECT
  180.         movea.l    (a0),a0
  181.     #endif
  182.         move._    d6,(a0)
  183.  
  184. ;;
  185. ;
  186. ;  call constructor
  187. ;
  188. ;;
  189.  
  190.         move._    ClassInfo_(constructor)(a2),d1
  191.         beq.s    @5                    ;  class has no constructor
  192. ;
  193.         movea._    d1,a0
  194.     #ifdef BASE_REG
  195.         adda.l    BASE_REG,a0
  196.     #endif
  197.         move.l    d7,-(sp)
  198.         jsr        (a0)
  199.         addq.l    #4,sp
  200. @5        ;rts
  201.     }
  202. }
  203.